package org.oos.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.oos.atom.elements.Link;
import org.oos.atom.elements.Text;
import org.oos.atom.entries.MultimediaEntry;

public class OosImage extends OosMedia implements Serializable {

	private static final long serialVersionUID = 7620751014868872554L;

	public static final String REL = "media";

	/**
	 * Default Avatar, the location of this avatar is: <br />
	 * <img src="http://11870.com/multimedia/avatar/xg_avatar.png"> <br />
	 * <a href="http://11870.com/multimedia/avatar/xg_avatar.png"
	 * >http://11870.com/multimedia/avatar/xg_avatar.png</a>
	 * 
	 */
	public static final OosImage DEFAULT_IMAGE = new OosImage();

	/**
	 * This enumeration describes the Sized that an image may come in:
	 * 
	 * <table border="1">
	 * <tr>
	 * <td>Small</td>
	 * <td>Medium</td>
	 * <td>Large</td>
	 * <td>Extra Large</td>
	 * </tr>
	 * <tr>
	 * <td>66x66</td>
	 * <td>92x92</td>
	 * <td>320x320</td>
	 * <td>640x640</td>
	 * </tr>
	 * </table>
	 * 
	 * @author pablo.gonzalez@11870.com
	 * 
	 */
	public enum ImageSize {
		SMALL("ps", 66, 66), MEDIUM("pm", 92, 92), LARGE("pl", 320, 320), XLARGE(
				"pxl", 640, 640);

		private String name;
		public int width;
		public int height;
		private Map<OosImage, String> pathCache = new WeakHashMap<OosImage, String>();

		private ImageSize(String smallName, int width, int height) {
			this.name = smallName;
			this.width = width;
			this.height = height;
		}

		PathFinder<OosImage> PATH_FINDER = new PathFinder<OosImage>() {

			@Override
			public CharSequence getPath(OosImage image) {
				if (!pathCache.containsKey(image)) {
					String resultUrl;
					if (image.getPath() != null) {
						resultUrl = image.getPath().toString();
					} else {
						// if there is no link add the default Avatar path
						resultUrl = DEFAULT_PATH;
					}
					// if it is the same size as original
					if (!resultUrl.contains(name)) {
						// check if the original is of other size and
						for (ImageSize size : values()) {
							if (resultUrl.contains(size.name)) {
								resultUrl = resultUrl.replace(size.name, name);
							}
						}
					}
					pathCache.put(image, resultUrl);
				}
				return pathCache.get(image);
			}
		};
	}

	public OosImage() {

	}

	final static Creator<OosImage> CREATOR = new Creator<OosImage>() {

		@Override
		public OosImage create(MultimediaEntry entry) {
			Text content = entry.getContent();
			return OosImage.create(content.getSrc(), content.getType());
		}
	};

	public static OosImage create(CharSequence path, CharSequence type) {
		OosImage image = new OosImage();
		image.setPath(path);
		image.setType(type);
		return image;
	}

	public static OosImage create(Link link) {
		return create(link.getHref(), link.getType());
	}

	public CharSequence getPath(MediaSize size) {
		return size.toSize(ImageSize.values()).PATH_FINDER.getPath(this);
	};

	public static List<OosImage> getImages(List<Link> links) {
		List<OosImage> images = new ArrayList<OosImage>();
		for (Link link : Link.find(links, REL)) {
			images.add(create(link));
		}
		return images;
	}

}
